package com.bookworld.model;

import jakarta.validation.constraints.*;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.annotation.NumberFormat;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.List;

public class Book {
    private Long id;

    @NotBlank(message = "{book.title.notblank}")
    @Size(max = 200, message = "{book.title.size}")
    private String title;

    @NotBlank(message = "{book.isbn.notblank}")
    @Pattern(regexp = "^(?:ISBN(?:-1[03])?:? )?(?=[0-9X]{10}$|(?=(?:[0-9]+[- ]){3})[- 0-9X]{13}$|97[89][0-9]{10}$|(?=(?:[0-9]+[- ]){4})[- 0-9]{17}$)(?:97[89][- ]?)?[0-9]{1,5}[- ]?[0-9]+[- ]?[0-9]+[- ]?[0-9X]$",
            message = "{book.isbn.invalid}")
    private String isbn;

    @NotBlank(message = "{book.description.notblank}")
    @Size(max = 2000, message = "{book.description.size}")
    private String description;

    @NotNull(message = "{book.price.notnull}")
    @DecimalMin(value = "0.01", message = "{book.price.min}")
    @NumberFormat(pattern = "#,##0.00")
    private BigDecimal price;

    @NotNull(message = "{book.discountPrice.notnull}")
    @DecimalMin(value = "0.00", message = "{book.discountPrice.min}")
    @NumberFormat(pattern = "#,##0.00")
    private BigDecimal discountPrice;

    @NotNull(message = "{book.stock.notnull}")
    @Min(value = 0, message = "{book.stock.min}")
    private Integer stock;

    @NotNull(message = "{book.pages.notnull}")
    @Min(value = 1, message = "{book.pages.min}")
    private Integer pages;

    @NotBlank(message = "{book.language.notblank}")
    private String language;

    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate publishDate;

    private String coverImage;
    private String publisher;
    private String edition;
    private String format;
    private Double weight;
    private String dimensions;

    @NotNull(message = "{book.category.notnull}")
    private Long categoryId;

    @NotNull(message = "{book.author.notnull}")
    private Long authorId;

    private Boolean active;
    private Boolean featured;
    private Integer viewCount;
    private Integer soldCount;
    private BigDecimal rating;

    private LocalDateTime createdAt;
    private LocalDateTime updatedAt;

    // 关联对象
    private Category category;
    private Author author;
    private List<Review> reviews;

    // 计算属性
    public BigDecimal getFinalPrice() {
        return discountPrice != null && discountPrice.compareTo(BigDecimal.ZERO) > 0 
                ? discountPrice : price;
    }

    public BigDecimal getDiscountAmount() {
        return discountPrice != null && discountPrice.compareTo(BigDecimal.ZERO) > 0 
                ? price.subtract(discountPrice) : BigDecimal.ZERO;
    }

    public Double getDiscountPercentage() {
        if (discountPrice != null && discountPrice.compareTo(BigDecimal.ZERO) > 0) {
            return price.subtract(discountPrice)
                    .divide(price, 4, BigDecimal.ROUND_HALF_UP)
                    .multiply(BigDecimal.valueOf(100))
                    .doubleValue();
        }
        return 0.0;
    }

    public boolean isInStock() {
        return stock != null && stock > 0;
    }

    public boolean isLowStock() {
        return stock != null && stock <= 5;
    }

    // 构造函数
    public Book() {
        this.active = true;
        this.featured = false;
        this.viewCount = 0;
        this.soldCount = 0;
        this.rating = BigDecimal.ZERO;
    }

    // Getters and Setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public BigDecimal getPrice() {
        return price;
    }

    public void setPrice(BigDecimal price) {
        this.price = price;
    }

    public BigDecimal getDiscountPrice() {
        return discountPrice;
    }

    public void setDiscountPrice(BigDecimal discountPrice) {
        this.discountPrice = discountPrice;
    }

    public Integer getStock() {
        return stock;
    }

    public void setStock(Integer stock) {
        this.stock = stock;
    }

    public Integer getPages() {
        return pages;
    }

    public void setPages(Integer pages) {
        this.pages = pages;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    public LocalDate getPublishDate() {
        return publishDate;
    }

    public void setPublishDate(LocalDate publishDate) {
        this.publishDate = publishDate;
    }

    public String getCoverImage() {
        return coverImage;
    }

    public void setCoverImage(String coverImage) {
        this.coverImage = coverImage;
    }

    public String getPublisher() {
        return publisher;
    }

    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public String getEdition() {
        return edition;
    }

    public void setEdition(String edition) {
        this.edition = edition;
    }

    public String getFormat() {
        return format;
    }

    public void setFormat(String format) {
        this.format = format;
    }

    public Double getWeight() {
        return weight;
    }

    public void setWeight(Double weight) {
        this.weight = weight;
    }

    public String getDimensions() {
        return dimensions;
    }

    public void setDimensions(String dimensions) {
        this.dimensions = dimensions;
    }

    public Long getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Long categoryId) {
        this.categoryId = categoryId;
    }

    public Long getAuthorId() {
        return authorId;
    }

    public void setAuthorId(Long authorId) {
        this.authorId = authorId;
    }

    public Boolean getActive() {
        return active;
    }

    public void setActive(Boolean active) {
        this.active = active;
    }

    public Boolean getFeatured() {
        return featured;
    }

    public void setFeatured(Boolean featured) {
        this.featured = featured;
    }

    public Integer getViewCount() {
        return viewCount;
    }

    public void setViewCount(Integer viewCount) {
        this.viewCount = viewCount;
    }

    public Integer getSoldCount() {
        return soldCount;
    }

    public void setSoldCount(Integer soldCount) {
        this.soldCount = soldCount;
    }

    public BigDecimal getRating() {
        return rating;
    }

    public void setRating(BigDecimal rating) {
        this.rating = rating;
    }

    public LocalDateTime getCreatedAt() {
        return createdAt;
    }

    public void setCreatedAt(LocalDateTime createdAt) {
        this.createdAt = createdAt;
    }

    public LocalDateTime getUpdatedAt() {
        return updatedAt;
    }

    public void setUpdatedAt(LocalDateTime updatedAt) {
        this.updatedAt = updatedAt;
    }

    public Category getCategory() {
        return category;
    }

    public void setCategory(Category category) {
        this.category = category;
    }

    public Author getAuthor() {
        return author;
    }

    public void setAuthor(Author author) {
        this.author = author;
    }

    public List<Review> getReviews() {
        return reviews;
    }

    public void setReviews(List<Review> reviews) {
        this.reviews = reviews;
    }

    @Override
    public String toString() {
        return "Book{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", isbn='" + isbn + '\'' +
                ", price=" + price +
                ", stock=" + stock +
                '}';
    }
}
